package org.brownflat.watergate.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * <p>&copy Rupert Jones 2012</p>
 *
 * @author rup
 */
@Entity
@Table(name = "wgate_auto_review_trigger")
public class ReviewTrigger extends BaseEntity {

    @Column(name="name")
    private String name;

    @ManyToOne
    @JoinColumn(name="branch")
    private Branch branch;

    @ManyToOne
    @JoinColumn(name="group_match")
    private Group group;

    @Column(name="file_match")
    private String fileMatch;

    @Column(name="all_commits")
    private boolean allCommits;

    @ManyToOne
    @JoinColumn(name="user_match")
    private User userMatch;

    @Column(name="enabled")
    private boolean enabled;

    @Column(name="file_count_match")
    private int fileCountMatch;

    @Column(name="start_revision")
    private long startRevision;

    @Column(name="msg_match")
    private String messageMatch;

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }

    private boolean matchGroup(Commit commit) {
        if(group != null) {
            User user = commit.getUser();
            return user.isInGroup(group);
        }
        return false;
    }

    public Branch getBranch() {
        return branch;
    }

    public void setBranch(Branch branch) {
        this.branch = branch;
    }

    public String getFileMatch() {
        return fileMatch;
    }

    public void setFileMatch(String fileMatch) {
        this.fileMatch = fileMatch;
    }

    private boolean matchFile(Commit commit) {
        if(fileMatch != null) {
            for(CommitElement commitElement : commit.getCommitElements()) {
                if (commitElement.getFullPath().matches(fileMatch)) {
                    return true;
                }
            }
        }
        return false;
    }

    public String getMessageMatch() {
        return messageMatch;
    }

    public void setMessageMatch(String messageMatch) {
        this.messageMatch = messageMatch;
    }

    private boolean matchMessage(Commit commit) {
        if(messageMatch != null) {
            String message = commit.getMessage();
            return (message != null && message.contains(messageMatch));
        }
        return false;
    }

    public boolean isAllCommits() {
        return allCommits;
    }

    public void setAllCommits(boolean allCommits) {
        this.allCommits = allCommits;
    }

    public User getUserMatch() {
        return userMatch;
    }

    public void setUserMatch(User userMatch) {
        this.userMatch = userMatch;
    }

    private boolean matchUser(Commit commit) {
        return userMatch != null && (commit.getUser().getId() == userMatch.getId());
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public long getStartRevision() {
        return startRevision;
    }

    public void setStartRevision(long startRevision) {
        this.startRevision = startRevision;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getFileCountMatch() {
        return fileCountMatch;
    }

    public void setFileCountMatch(int fileCountMatch) {
        this.fileCountMatch = fileCountMatch;
    }

    private boolean matchFileCount(Commit commit) {
        return fileCountMatch > 0 && commit.countCommitElements(CommitElementType.FILE) >= fileCountMatch;
    }

    public boolean match(Commit commit) {
        return isEnabled() && commit.getRevision() >= getStartRevision() &&
                (isAllCommits() || matchFileCount(commit) || matchUser(commit)
                || matchFile(commit) || matchMessage(commit) || matchGroup(commit));
    }
}
